﻿using System;
using System.Windows.Forms;
using ProdControls.NativePatterns.MessageConstants;
using ProdControls.Utility;

namespace ProdControls
{
    /// <summary>
    ///   Methods to work with Checkbox controls using the UI Automation framework
    /// </summary>
    internal static class ProdCheckBoxNative
    {
        /// <summary>
        ///   Uses SendMessage to check the state
        /// </summary>
        /// <param name="windowHandle"> Handle to the checkbox </param>
        /// <returns> one of the <see cref="System.Windows.Automation.ToggleState" /> ToggleStates </returns>
        internal static CheckState GetCheckStateNative(IntPtr windowHandle)
        {
            /* get valid ButtonCheckStates */
            int bcs = (int) NativeMethods.SendMessage(windowHandle, (int) ButtonMessages.BM_GETCHECK, 0, 0);

            return ConvertButtonStates(bcs);
        }

        /// <summary>
        ///   Uses SendMessage to post the state
        /// </summary>
        /// <param name="windowHandle"> Handle to the checkbox </param>
        /// <param name="isChecked"> one of the <see cref="System.Windows.Automation.ToggleState" /> ToggleStates </param>
        /// <returns> true if successfully verified </returns>
        internal static void SetCheckStateNative(IntPtr windowHandle, CheckState isChecked)
        {
            ButtonStates bst = ConvertToggleStates(isChecked);

            /* send the message */
            NativeMethods.SendMessage(windowHandle, (int) ButtonMessages.BM_SETSTATE, (int) bst, 0);
        }

        internal static void ToggleCheckStateNative(IntPtr windowHandle)
        {
            if (GetCheckStateNative(windowHandle) == CheckState.Checked)
                SetCheckStateNative(windowHandle, CheckState.Unchecked);
            else SetCheckStateNative(windowHandle, CheckState.Checked);
        }

        /// <summary>
        ///   Converts Automation ToggleStates to Win32 BST
        /// </summary>
        /// <param name="isChecked"> <see cref="System.Windows.Automation.ToggleState" /> </param>
        /// <returns> <see cref="ButtonStates" /> </returns>
        internal static ButtonStates ConvertToggleStates(CheckState isChecked)
        {
            ButtonStates bst;

            /* Convert to button state */
            switch (isChecked)
            {
                case CheckState.Indeterminate:
                    bst = ButtonStates.BST_INDETERMINATE;
                    break;
                case CheckState.Unchecked:
                    bst = ButtonStates.BST_UNCHECKED;
                    break;
                case CheckState.Checked:
                    bst = ButtonStates.BST_CHECKED;
                    break;
                default:
                    bst = ButtonStates.BST_INDETERMINATE;
                    break;
            }
            return bst;
        }

        /// <summary>
        ///   Converts Win32 BST_ to Automation ToggleStates
        /// </summary>
        /// <param name="bcs"> <see cref="ButtonStates" /> </param>
        /// <returns> <see cref="System.Windows.Automation.ToggleState" /> </returns>
        internal static CheckState ConvertButtonStates(int bcs)
        {
            switch (bcs)
            {
                case (int) ButtonStates.BST_UNCHECKED:
                    return CheckState.Unchecked;
                case (int) ButtonStates.BST_CHECKED:
                    return CheckState.Checked;
                case (int) ButtonStates.BST_INDETERMINATE:
                    return CheckState.Indeterminate;
            }
            return CheckState.Indeterminate;
        }
    }
}